﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using ActivePal.Properties;
using System.IO;
using ActivePalInterop.Data;
using ActivePalInterop;
using ActivePalInterop.Events;
using System.ComponentModel;

namespace ActivePal
{
    public partial class Main : Window
    {
        #region Backgroun workers declaration

        private BackgroundWorker workerReader;
        private BackgroundWorker workerBulkUploader;

        #endregion

        #region Load worker events

        /// <summary>
        /// Occurs every cerain iteration, say 10 000 and is rised by uploader. 
        /// Even forwarding to the worker thread
        /// </summary>        
        private void uploader_ReadRowsPulse(object sender, ProgressBarLablesEventArgs args)
        {
            workerReader.ReportProgress(0, args);
        }

        /// <summary>
        /// Update GUI with progress changed data
        /// </summary>        
        private void workerReader_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            ProgressBarLablesEventArgs args = (ProgressBarLablesEventArgs)e.UserState;
            titledProgressBar.UpdateControlLabels(args.MajorLableText, args.MinorLableText);
        }

        /// <summary>
        /// The load to cache has finished
        /// </summary>        
        private void workerReader_Completed(object sender, RunWorkerCompletedEventArgs e)
        {
            UpdateGUIWorkStopped();

            if (e.Cancelled)
            {
                OutputDebugMessage("Read work cancelled");
                titledProgressBar.UpdateControl(0, "Cancelled", ":(");
                return;
            }

            //start loading to db
            workerBulkUploader.RunWorkerAsync();
        }

        /// <summary>
        /// Start uploading date to the local cache
        /// </summary>        
        private void workerReader_DoWork(object sender, DoWorkEventArgs e)
        {
            UpdateGUIWorkStarted();

            if (PeopleViewCtrl.SelectedItems == null ||
                       PeopleViewCtrl.SelectedItems.Count == 0 ||
                       PeopleViewCtrl.SelectedItems.Count > 1)
            {
                MessageBox.Show("Please selsect one person for whom monitoring has been done.");
                workerReader.CancelAsync();
            }

            if (workerReader.CancellationPending)
            {
                e.Cancel = true;
                return;
            }
            //get file name
            UploadFileName = Convert.ToString(e.Argument);

            //get header counts
            SkippedHeaderCount = Settings.Default.SkipHeaderRows;

            SessionName = String.Format("{0}_{1}",
                Settings.Default.SessionHeader,
                Settings.Default.SessionCounter);

            if (File.Exists(UploadFileName))
            {
                //using StreamReader to read
                using (StreamReader s = new StreamReader(UploadFileName))
                {
                    Person p = (Person)PeopleViewCtrl.SelectedItems[0];

                    IUploadableData details = new DecompressedPalData();
                    details.SkippedHeaderCount = SkippedHeaderCount;

                    int commitSize = Settings.Default.CommitSize;
                    Uploader uploader = new Uploader(details.TableName, commitSize, details.Columns, p);
                    uploader.ReadRowsPulse += new ReadRowsPulseEventHandler(uploader_ReadRowsPulse);
                    uploader.DebugMessage += new MessageEventHandler(uploader_DebugMessage);
                    uploader.CurrentSession.SessionName = SessionName;
                    uploader.CurrentSession.SessionComments = SessionComments;

                    

                    int importedRows = uploader.Load(s, details, sender as BackgroundWorker, e);
                    OutputDebugMessage("Total number of rows: " + importedRows);
                    CurrentUploader = uploader;
                }
            }
        }

        /// <summary>
        /// Handling debug messages
        /// </summary>        
        private void uploader_DebugMessage(object sender, MessageEventArgs args)
        {
            OutputDebugMessage(args.Message);
        }

        #endregion

        #region Bulk Insert worker events

        /// <summary>
        /// Update GUI with progress changed data
        /// </summary>   
        private void workerBulkUploader_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            ProgressControlEventArgs args = (ProgressControlEventArgs)e.UserState;
            titledProgressBar.UpdateControl(e.ProgressPercentage, args.MajorLableText, args.MinorLableText);
        }

        /// <summary>
        /// Upload to database has finished
        /// </summary>  
        private void workerBulkUploader_Completed(object sender, RunWorkerCompletedEventArgs e)
        {
            UpdateGUIWorkStopped();
            UpdateSettingsAfterUpload();

            if (e.Cancelled)
            {
                OutputDebugMessage("Bulk insert work cancelled");
                titledProgressBar.UpdateControl(0, "Cancelled", ":(");
                return;
            }
            else
            {
                titledProgressBar.UpdateControl(100, "Done.", e.Result.ToString());
            }
        }

        /// <summary>
        /// Updates settings after data has been uploaded to the database;
        /// </summary>
        private void UpdateSettingsAfterUpload()
        {
            Settings.Default.SessionCounter += 1;
            Settings.Default.Save();
        }

        /// <summary>
        /// Start uploading date to the database
        /// </summary> 
        private void workerBulkUploader_DoWork(object sender, DoWorkEventArgs e)
        {
            UpdateGUIWorkStarted();
            Uploader uploader = CurrentUploader; //get uploader in a saved state
            uploader.BulkInsertPulse += new ProgressControlEventHandler(uploader_BulkInsertPulse);
            uploader.Flush(sender as BackgroundWorker, e);
        }

        /// <summary>
        /// Handling debug messages
        /// </summary>
        private void uploader_BulkInsertPulse(object sender, ProgressControlEventArgs args)
        {
            workerBulkUploader.ReportProgress(args.ProgressPercentage, args);
        }

        #endregion


    }
}
